From fa6b5eb32b6f1206d44ea26e0d58ab8ca017ccc0 Mon Sep 17 00:00:00 2001 From: "cl349@freefall.cl.cam.ac.uk" Date: Thu, 12 Aug 2004 17:34:21 +0000 Subject: [PATCH] bitkeeper revision 1.1159.17.21 (411baa1dkWXzaVHGnr6yk4SeGTJAHA) Merge 2.4/2.6 shutdown/suspend control message handling code. --- .../arch/xen/kernel/setup.c | 170 --------------- .../arch/xen/i386/kernel/time.c | 27 ++- .../arch/xen/kernel/reboot.c | 196 ++++++++++++++++++ .../asm-xen/asm-i386/mach-xen/irq_vectors.h | 3 + 4 files changed, 222 insertions(+), 174 deletions(-) diff --git a/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c b/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c index 9b740aaaa8..4922d661b4 100644 --- a/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c +++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c @@ -1184,173 +1184,3 @@ void __init cpu_init (void) current->used_math = 0; stts(); } - - -/****************************************************************************** - * Stop/pickle callback handling. - */ - -#include - -/* Ignore multiple shutdown requests. */ -static int shutting_down = -1; - -static void __do_suspend(void) -{ - int i,j; - /* Hmmm... a cleaner interface to suspend/resume blkdevs would be nice. */ - extern void blkdev_suspend(void); - extern void blkdev_resume(void); - extern void netif_suspend(void); - extern void netif_resume(void); - extern void time_suspend(void); - extern void time_resume(void); - - suspend_record_t *suspend_record = NULL; - - if ( (suspend_record = (suspend_record_t *)__get_free_page(GFP_KERNEL)) - == NULL ) - goto out; - - suspend_record->nr_pfns = max_pfn; /* final number of pfns */ - - __cli(); - - netif_suspend(); - - blkdev_suspend(); - - time_suspend(); - - ctrl_if_suspend(); - - irq_suspend(); - - HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page; - clear_fixmap(FIX_SHARED_INFO); - - memcpy(&suspend_record->resume_info, &start_info, sizeof(start_info)); - - HYPERVISOR_suspend(virt_to_machine(suspend_record) >> PAGE_SHIFT); - - shutting_down = -1; - - memcpy(&start_info, &suspend_record->resume_info, sizeof(start_info)); - - set_fixmap(FIX_SHARED_INFO, start_info.shared_info); - - HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); - - memset(empty_zero_page, 0, PAGE_SIZE); - - for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ ) - { - pfn_to_mfn_frame_list[j] = - virt_to_machine(&phys_to_machine_mapping[i]) >> PAGE_SHIFT; - } - HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list = - virt_to_machine(pfn_to_mfn_frame_list) >> PAGE_SHIFT; - - - irq_resume(); - - ctrl_if_resume(); - - time_resume(); - - blkdev_resume(); - - netif_resume(); - - __sti(); - - - out: - if ( suspend_record != NULL ) - free_page((unsigned long)suspend_record); -} - -static int shutdown_process(void *__unused) -{ - static char *envp[] = { "HOME=/", "TERM=linux", - "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; - static char *restart_argv[] = { "/sbin/shutdown", "-r", "now", NULL }; - static char *poweroff_argv[] = { "/sbin/halt", "-p", NULL }; - - extern asmlinkage long sys_reboot(int magic1, int magic2, - unsigned int cmd, void *arg); - - daemonize(); - - switch ( shutting_down ) - { - case CMSG_SHUTDOWN_POWEROFF: - if ( execve("/sbin/halt", poweroff_argv, envp) < 0 ) - { - sys_reboot(LINUX_REBOOT_MAGIC1, - LINUX_REBOOT_MAGIC2, - LINUX_REBOOT_CMD_POWER_OFF, - NULL); - } - break; - - case CMSG_SHUTDOWN_REBOOT: - if ( execve("/sbin/shutdown", restart_argv, envp) < 0 ) - { - sys_reboot(LINUX_REBOOT_MAGIC1, - LINUX_REBOOT_MAGIC2, - LINUX_REBOOT_CMD_RESTART, - NULL); - } - break; - } - - return 0; -} - -static void __shutdown_handler(void *unused) -{ - int err; - - if ( shutting_down != CMSG_SHUTDOWN_SUSPEND ) - { - err = kernel_thread(shutdown_process, NULL, CLONE_FS | CLONE_FILES); - if ( err < 0 ) - printk(KERN_ALERT "Error creating shutdown process!\n"); - else - shutting_down = -1; /* could try again */ - } - else - { - __do_suspend(); - } -} - -static void shutdown_handler(ctrl_msg_t *msg, unsigned long id) -{ - static struct tq_struct shutdown_tq; - - if ( (shutting_down == -1) && - ((msg->subtype == CMSG_SHUTDOWN_POWEROFF) || - (msg->subtype == CMSG_SHUTDOWN_REBOOT) || - (msg->subtype == CMSG_SHUTDOWN_SUSPEND)) ) - { - shutting_down = msg->subtype; - shutdown_tq.routine = __shutdown_handler; - schedule_task(&shutdown_tq); - } - else - { - printk("Ignore spurious shutdown request\n"); - } - - ctrl_if_send_response(msg); -} - -static int __init setup_shutdown_event(void) -{ - ctrl_if_register_receiver(CMSG_SHUTDOWN, shutdown_handler, 0); - return 0; -} - -__initcall(setup_shutdown_event); diff --git a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/time.c b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/time.c index 425bde130c..6fa51ede40 100644 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/time.c +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/time.c @@ -510,7 +510,7 @@ unsigned long get_cmos_time(void) static long clock_cmos_diff; -static int time_suspend(struct sys_device *dev, u32 state) +static int __time_suspend(struct sys_device *dev, u32 state) { /* * Estimate time zone so that set_time can update the clock @@ -520,7 +520,7 @@ static int time_suspend(struct sys_device *dev, u32 state) return 0; } -static int time_resume(struct sys_device *dev) +static int __time_resume(struct sys_device *dev) { unsigned long sec = get_cmos_time() + clock_cmos_diff; write_seqlock_irq(&xtime_lock); @@ -531,8 +531,8 @@ static int time_resume(struct sys_device *dev) } static struct sysdev_class pit_sysclass = { - .resume = time_resume, - .suspend = time_suspend, + .resume = __time_resume, + .suspend = __time_suspend, set_kset_name("pit"), }; @@ -647,6 +647,25 @@ int set_timeout_timer(void) return ret; } +void time_suspend(void) +{ +} + +void time_resume(void) +{ + unsigned long flags; + write_lock_irqsave(&xtime_lock, flags); + /* Get timebases for new environment. */ + __get_time_values_from_xen(); + /* Reset our own concept of passage of system time. */ + processed_system_time = shadow_system_time; + /* Accept a warp in UTC (wall-clock) time. */ + last_seen_tv.tv_sec = 0; + /* Make sure we resync UTC time with Xen on next timer interrupt. */ + last_update_from_xen = 0; + write_unlock_irqrestore(&xtime_lock, flags); +} + /* * /proc/sys/xen: This really belongs in another file. It can stay here for * now however. diff --git a/linux-2.6.7-xen-sparse/arch/xen/kernel/reboot.c b/linux-2.6.7-xen-sparse/arch/xen/kernel/reboot.c index f8c0f246ca..d3679ef76b 100644 --- a/linux-2.6.7-xen-sparse/arch/xen/kernel/reboot.c +++ b/linux-2.6.7-xen-sparse/arch/xen/kernel/reboot.c @@ -1,8 +1,19 @@ +#define __KERNEL_SYSCALLS__ +static int errno; +#include #include +#include +#include +#include #include #include +#include +#include +#include #include +#include +#include #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) int reboot_thru_bios = 0; /* for dmi_scan.c */ @@ -40,3 +51,188 @@ void machine_power_off(void) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) EXPORT_SYMBOL(machine_power_off); #endif + + + +/****************************************************************************** + * Stop/pickle callback handling. + */ + +#include + +/* Ignore multiple shutdown requests. */ +static int shutting_down = -1; + +static void __do_suspend(void) +{ + int i,j; + /* Hmmm... a cleaner interface to suspend/resume blkdevs would be nice. */ + extern void blkdev_suspend(void); + extern void blkdev_resume(void); + extern void netif_suspend(void); + extern void netif_resume(void); + extern void time_suspend(void); + extern void time_resume(void); + extern unsigned long max_pfn; + extern unsigned long *pfn_to_mfn_frame_list; + + suspend_record_t *suspend_record = NULL; + + if ( (suspend_record = (suspend_record_t *)__get_free_page(GFP_KERNEL)) + == NULL ) + goto out; + + suspend_record->nr_pfns = max_pfn; /* final number of pfns */ + + __cli(); + + netif_suspend(); + + blkdev_suspend(); + + time_suspend(); + + ctrl_if_suspend(); + + irq_suspend(); + + HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page; + clear_fixmap(FIX_SHARED_INFO); + + memcpy(&suspend_record->resume_info, &start_info, sizeof(start_info)); + + HYPERVISOR_suspend(virt_to_machine(suspend_record) >> PAGE_SHIFT); + + shutting_down = -1; + + memcpy(&start_info, &suspend_record->resume_info, sizeof(start_info)); + + set_fixmap(FIX_SHARED_INFO, start_info.shared_info); + + HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); + + memset(empty_zero_page, 0, PAGE_SIZE); + + for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ ) + { + pfn_to_mfn_frame_list[j] = + virt_to_machine(&phys_to_machine_mapping[i]) >> PAGE_SHIFT; + } + HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list = + virt_to_machine(pfn_to_mfn_frame_list) >> PAGE_SHIFT; + + + irq_resume(); + + ctrl_if_resume(); + + time_resume(); + + blkdev_resume(); + + netif_resume(); + + __sti(); + + + out: + if ( suspend_record != NULL ) + free_page((unsigned long)suspend_record); +} + +static int shutdown_process(void *__unused) +{ + static char *envp[] = { "HOME=/", "TERM=linux", + "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; + static char *restart_argv[] = { "/sbin/shutdown", "-r", "now", NULL }; + static char *poweroff_argv[] = { "/sbin/halt", "-p", NULL }; + + extern asmlinkage long sys_reboot(int magic1, int magic2, + unsigned int cmd, void *arg); + + daemonize( +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + "shutdown" +#endif + ); + + switch ( shutting_down ) + { + case CMSG_SHUTDOWN_POWEROFF: + if ( execve("/sbin/halt", poweroff_argv, envp) < 0 ) + { + sys_reboot(LINUX_REBOOT_MAGIC1, + LINUX_REBOOT_MAGIC2, + LINUX_REBOOT_CMD_POWER_OFF, + NULL); + } + break; + + case CMSG_SHUTDOWN_REBOOT: + if ( execve("/sbin/shutdown", restart_argv, envp) < 0 ) + { + sys_reboot(LINUX_REBOOT_MAGIC1, + LINUX_REBOOT_MAGIC2, + LINUX_REBOOT_CMD_RESTART, + NULL); + } + break; + } + + shutting_down = -1; /* could try again */ + + return 0; +} + +static void __shutdown_handler(void *unused) +{ + int err; + + if ( shutting_down != CMSG_SHUTDOWN_SUSPEND ) + { + err = kernel_thread(shutdown_process, NULL, CLONE_FS | CLONE_FILES); + if ( err < 0 ) + printk(KERN_ALERT "Error creating shutdown process!\n"); + } + else + { + __do_suspend(); + } +} + +static void shutdown_handler(ctrl_msg_t *msg, unsigned long id) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL); +#else + static struct tq_struct shutdown_tq; +#endif + + if ( (shutting_down == -1) && + ((msg->subtype == CMSG_SHUTDOWN_POWEROFF) || + (msg->subtype == CMSG_SHUTDOWN_REBOOT) || + (msg->subtype == CMSG_SHUTDOWN_SUSPEND)) ) + { + shutting_down = msg->subtype; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + schedule_work(&shutdown_work); +#else + shutdown_tq.routine = __shutdown_handler; + schedule_task(&shutdown_tq); +#endif + } + else + { + printk("Ignore spurious shutdown request\n"); + } + + ctrl_if_send_response(msg); +} + +static int __init setup_shutdown_event(void) +{ + ctrl_if_register_receiver(CMSG_SHUTDOWN, shutdown_handler, 0); + return 0; +} + +__initcall(setup_shutdown_event); diff --git a/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h b/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h index 8de8846125..b8384efc53 100644 --- a/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h +++ b/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h @@ -140,6 +140,9 @@ extern int bind_virq_to_irq(int virq); extern void unbind_virq_from_irq(int virq); extern int bind_evtchn_to_irq(int evtchn); extern void unbind_evtchn_from_irq(int evtchn); + +extern void irq_suspend(void); +extern void irq_resume(void); #endif /* __ASSEMBLY__ */ #endif /* _ASM_IRQ_VECTORS_H */ -- 2.30.2